package org.example.rabbitmq.concurrent.mq;

import org.example.rabbitmq.concurrent.lock.RamRateLimiter;
import org.example.rabbitmq.concurrent.lock.RateLimiter;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConsumerConfig {
    @Autowired
    ApplicationContext applicationContext;

    @Bean
    public Queue concurrentQueue() {
        Queue queue = new Queue("concurrent-queue", true, false, false);
//        queue.addArgument("x-dead-letter-exchange", "dlx.exchange");
        return queue;
    }

    @Bean
    public Queue concurrentQueue2() {
        Queue queue = new Queue("concurrent-queue2", true, false, false);
//        queue.addArgument("x-dead-letter-exchange", "dlx.exchange");
        return queue;
    }

    @Bean
    public RateLimiter ramRateLimiter() {
        return new RamRateLimiter("concurrent-queue", "concurrent-queue2");
    }

    @Bean
    public ConcurrentTestConsumer concurrentTestConsumer() {
        ConcurrentTestConsumer consumer = new ConcurrentTestConsumer();
//        applicationContext.getAutowireCapableBeanFactory().autowireBean(consumer);
        return consumer;
    }

    @Bean
    public SimpleMessageListenerContainer concurrentTestMessageListener(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueueNames("concurrent-queue");
        container.setPrefetchCount(1);
        container.setBatchSize(1);
        container.setMessageListener(concurrentTestConsumer());
        container.setConcurrentConsumers(1);
//        container.setMaxConcurrentConsumers(1);
        container.setConsumerBatchEnabled(false);
        container.setDeclarationRetries(1);
//        container.setExclusive(true); // When the consumer is exclusive, the concurrency must be 1
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return container;
    }

    @Bean
    public SimpleMessageListenerContainer concurrentTestMessageListener2(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueueNames("concurrent-queue2");
        container.setPrefetchCount(1);
        container.setBatchSize(1);
        container.setMessageListener(concurrentTestConsumer());
        container.setConcurrentConsumers(1);
//        container.setMaxConcurrentConsumers(1);
        container.setConsumerBatchEnabled(false);
        container.setDeclarationRetries(1);
//        container.setExclusive(true); // When the consumer is exclusive, the concurrency must be 1
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return container;
    }

    @Bean
    public SimpleMessageListenerContainer concurrentTestMessageListener3(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueueNames("concurrent-queue");
        container.setPrefetchCount(1);
        container.setBatchSize(1);
        container.setMessageListener(concurrentTestConsumer());
        container.setConcurrentConsumers(1);
//        container.setMaxConcurrentConsumers(1);
        container.setConsumerBatchEnabled(false);
        container.setDeclarationRetries(1);
//        container.setExclusive(true); // When the consumer is exclusive, the concurrency must be 1
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return container;
    }

    @Bean
    public SimpleMessageListenerContainer concurrentTestMessageListener4(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueueNames("concurrent-queue2");
        container.setPrefetchCount(1);
        container.setBatchSize(1);
        container.setMessageListener(concurrentTestConsumer());
        container.setConcurrentConsumers(1);
//        container.setMaxConcurrentConsumers(1);
        container.setConsumerBatchEnabled(false);
        container.setDeclarationRetries(1);
//        container.setExclusive(true); // When the consumer is exclusive, the concurrency must be 1
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return container;
    }
}
